BNF for Junicon.jj

TOKENS

/*************************************************************************
 * Tokens
 ************************************************************************/

//========================================================================
// Tokens: White space
//========================================================================
<DEFAULT> SKIP : {
<WHITESPACE: " " | "\t" | "\f">
}

   
<DEFAULT> SPECIAL : {
<NEWLINE: "\n" | "\r" | "\r\n">
}

   
//========================================================================
// Tokens: Comments
//========================================================================
<DEFAULT> TOKEN : {
<ANNOTATION_COMMENT_PREFIX: "#@<">
| <#REST_OF_LINE: (~["\n","\r"])* ("\n" | "\r" | "\r\n")?>
}

   
<DEFAULT> SPECIAL : {
<SINGLE_LINE_COMMENT: "#" (~["\n","\r"])* ("\n" | "\r" | "\r\n")?>
}

   
//========================================================================
// Tokens: Reserved words
//========================================================================
<DEFAULT> TOKEN : {
<ABSTRACT: "abstract">
| <BREAK: "break">
| <BY: "by">
| <CASE: "case">
| <CLASS: "class">
| <CREATE: "create">
| <THREAD: "thread">
| <CRITICAL: "critical">
| <DEFAULT_token: "default">
| <DO: "do">
| <ELSE: "else">
| <END: "end">
| <EVERY: "every">
| <FAIL: "fail">
| <GLOBAL: "global">
| <IF: "if">
| <IMPORT: "import">
| <IN: "in">
| <INITIAL: "initial">
| <INITIALLY: "initially">
| <INVOCABLE: "invocable">
| <LINK: "link">
| <LOCAL: "local">
| <METHOD: "method">
| <NEW: "new">
| <NEXT: "next">
| <NOT: "not">
| <NULL_LITERAL: "null">
| <OF: "of">
| <PACKAGE: "package">
| <PROCEDURE: "procedure">
| <RECORD: "record">
| <REPEAT: "repeat">
| <RETURN: "return">
| <STATIC: "static">
| <SUSPEND: "suspend">
| <THEN: "then">
| <TO: "to">
| <UNTIL: "until">
| <WHILE: "while">
}

   
//========================================================================
// Tokens: Separators
//========================================================================
<DEFAULT> TOKEN : {
<LPAREN: "(">
| <RPAREN: ")">
| <LBRACE: "{">
| <RBRACE: "}">
| <LBRACKET: "[">
| <RBRACKET: "]">
| <SEMICOLON: ";">
| <COMMA: ",">
| <DOTDOTDOT: "...">
| <DOT: ".">
| <ANNOTATION: "@<">
| <AT: "@">
| <COMPR: "[:">
| <COMPREND: ":]">
| <COLON: ":">
| <COLONCOLON: "::">
| <LBRACE_EBCDIC: "$("> : {
| <RBRACE_EBCDIC: "$)"> : {
| <LBRACKET_EBCDIC: "$<"> : {
| <RBRACKET_EBCDIC: "$>"> : {
}

   
//========================================================================
// Tokens: Operators, grouped by precedence
//========================================================================
<DEFAULT> TOKEN : {
<AND: "&">
| <QMARK: "?">
| <ASSIGN: ":=">
| <REVASSIGN: "<-">
| <REVSWAP: "<->">
| <SWAP: ":=:">
| <PMATCH: "??">
| <POR: ".|">
| <BAR: "|">
| <PAND: "&&">
| <GT: ">">
| <LT: "<">
| <EQ: "==">
| <LE: "<=">
| <GE: ">=">
| <EQUALS: "=">
| <LSHIFT: "<<">
| <RSHIFT: ">>">
| <SLE: "<<=">
| <EQUIV: "===">
| <SGE: ">>=">
| <NMNE: "~=">
| <SNE: "~==">
| <NEQUIV: "~===">
| <PIMDASSN: "$$">
| <PASSNONMATCH: "->">
| <SND: "@>">
| <SNDBK: "@>>">
| <RCV: "<@">
| <RCVBK: "<<@">
| <CONCAT: "||">
| <LCONCAT: "|||">
| <PLUS: "+">
| <MINUS: "-">
| <INCR: "++">
| <DECR: "--">
| <STAR: "*">
| <SLASH: "/">
| <PERCENT: "%">
| <INTER: "**">
| <CARET: "^">
| <BANG: "!">
| <BACKSLASH: "\\">
| <TILDE: "~">
| <PSETCUR: ".$">
| <PIPE: "|>">
| <FUTURE: "|>>">
| <COEXPR: "|<>">
| <FIRSTCLASS: "<>">
| <PARALLEL: "|<>|">
| <BACKQUOTE: "`">
| <PCOLON: "+:">
| <MCOLON: "-:">
| <DOLLAR: "$">
| <AUGMOD: "%:=">
| <AUGAND: "&:=">
| <AUGSTAR: "*:=">
| <AUGINTER: "**:=">
| <AUGPLUS: "+:=">
| <AUGUNION: "++:=">
| <AUGMINUS: "-:=">
| <AUGDIFF: "--:=">
| <AUGSLASH: "/:=">
| <AUGNMLT: "<:=">
| <AUGSLT: "<<:=">
| <AUGSLE: "<<=:=">
| <AUGNMLE: "<=:=">
| <AUGNMEQ: "=:=">
| <AUGSEQ: "==:=">
| <AUGEQUIV: "===:=">
| <AUGNMGT: ">:=">
| <AUGNMGE: ">=:=">
| <AUGSGT: ">>:=">
| <AUGSGE: ">>=:=">
| <AUGQMARK: "?:=">
| <AUGAT: "@:=">
| <AUGCARET: "^:=">
| <AUGCONCAT: "||:=">
| <AUGNEQUIV: "~===:=">
| <AUGSNE: "~==:=">
| <AUGNMNE: "~=:=">
| <AUGLCONCAT: "|||:=">
}

   
//========================================================================
// Tokens: Numeric literals
//========================================================================
<DEFAULT> TOKEN : {
<INTEGER_LITERAL: <DECIMAL_LITERAL>>
| <RADIX_LITERAL: <DECIMAL_LITERAL> ["r","R"] (["0"-"9","a"-"f","A"-"F"])+>
| <#DECIMAL_LITERAL: (["0"-"9"])+>
| <REAL_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? | "." (["0"-"9"])+ (<EXPONENT>)? | (["0"-"9"])+ <EXPONENT>>
| <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
}

   
<DEFAULT> MORE : {
"\"" : WithinQuote
}

   
<WithinQuote> SKIP : {
<"_" <NEWLINE> (<WHITESPACE>)*> : WithinQuote
}

   
<WithinQuote> TOKEN : {
<STRING_LITERAL: "\""> : DEFAULT
}

   
<WithinQuote> MORE : {
<~["\"","\\"] | <ESCAPE_LITERAL>>
}

   
//====================
// Single quote -- multiline continuations are as for double quotes.
//====================
<DEFAULT> MORE : {
"\'" : WithinSingleQuote
}

   
<WithinSingleQuote> SKIP : {
<"_" <NEWLINE> (<WHITESPACE>)*> : WithinSingleQuote
}

   
<WithinSingleQuote> TOKEN : {
<SINGLE_QUOTE_LITERAL: "\'"> : DEFAULT
}

   
<WithinSingleQuote> MORE : {
<~["\'","\\"] | <ESCAPE_LITERAL>>
}

   
//====================
// Quote regex dependencies
//====================
<DEFAULT> TOKEN : {
<#OLD_SINGLE_QUOTE_LITERAL: "\'" (~["\'","\\"] | <ESCAPE_LITERAL>)* "\'">
| <#OLD_STRING_LITERAL: "\"" (~["\"","\\"] | <ESCAPE_LITERAL>)* "\"">
| <#ESCAPE_LITERAL: "\\" (<HEX_ESCAPE> | <OCTAL_ESCAPE> | <CONTROL_ESCAPE> | ["!"-"~"," ","\t","\n","\r","\f"])>
| <#ESCAPE_LITERAL_NO_NL: "\\" (<HEX_ESCAPE> | <OCTAL_ESCAPE> | <CONTROL_ESCAPE> | ["!"-"~"," ","\t","\f"])>
| <#HEX_ESCAPE: ["x","X"] <HEX_DIGITS>>
| <#OCTAL_ESCAPE: ["0"-"7"] ["0"-"7"]>
| <#CONTROL_ESCAPE: "^" ["!"-"~"]>
| <#HEX_DIGITS: ["0"-"9","a"-"f","A"-"F"]>
}

   
//========================================================================
// Tokens: Big literals (Block quotes, or Big quotes)
//========================================================================
<DEFAULT> TOKEN : {
<BIG_LITERAL: "{<" (~[">","}","\\"] | ">" ~["}","\\"] | ~[">","\\"] "}" | ">" <ESCAPE_LITERAL> | <ESCAPE_LITERAL> ("}")?)* ([">","}"])? ">}">
}

   
//========================================================================
// Tokens: Identifiers
//========================================================================
<DEFAULT> TOKEN : {
<IDENTIFIER: <IDENTIFIER_BASE>>
| <#IDENTIFIER_BASE: <ALPHA> (<ALPHA> | <DIGIT>)*>
| <#ALPHA: ["A"-"Z","a"-"z","_"]>
| <#LETTER: ["$","A"-"Z","_","a"-"z","\u00c0"-"\u00d6","\u00d8"-"\u00f6","\u00f8"-"\u00ff","\u0100"-"\u1fff","\u3040"-"\u318f","\u3300"-"\u337f","\u3400"-"\u3d2d","\u4e00"-"\u9fff","\uf900"-"\ufaff"]>
| <#DIGIT: ["0"-"9","\u0660"-"\u0669","\u06f0"-"\u06f9","\u0966"-"\u096f","\u09e6"-"\u09ef","\u0a66"-"\u0a6f","\u0ae6"-"\u0aef","\u0b66"-"\u0b6f","\u0be7"-"\u0bef","\u0c66"-"\u0c6f","\u0ce6"-"\u0cef","\u0d66"-"\u0d6f","\u0e50"-"\u0e59","\u0ed0"-"\u0ed9","\u1040"-"\u1049"]>
}

   

NON-TERMINALS

/*************************************************************************
 * LANGUAGE GRAMMAR STARTS HERE
 ************************************************************************/

//========================================================================
// Grammar
//========================================================================

/****
Tags for the generated XML syntax tree are as follows:

identifier		# Atoms
literal    @isInteger @isReal @isRadix (numbers)
literal	   @isQuote ("") @isSingleQuote ('') @isBigLiteral {< >}
literal    @isWord (null)
andKeyword &i
methodref  i.i::i | ((Cast) i).i::i	# i::i called packageref in Unicon
packagref  i.i::i		# type instead of reference in expression above
dotname    i.i	# introduced atom when transforming commands, new allocation

operator   @isAugment @isBoolean	# Operators
delimiter  @id ,;
keyword	   reserved word
assign     x := y
product    x & y

program			# Program, everything is expression
expression
type            # type, declaration, or atom used in expression
                # e.g., declaration/ identifier | dotname
		#       atom/ identifier | dotname
declaration @isGlobalVariable, @isLocalVariable, @isParameter, @isClassOrMethod
comment    #
newline

tuple      (e,e) | (e)	# Grouping
list       [e,e] | [e]	@isEmpty=true if empty list or map
block      {e;e} | {e}	@isClosure=true if body of closure
set        {e,e}
map        [e:e, ] | [e:e; ]
angleTuple  | 
comprehension [: e :]	# list comprehension

			# Expressions
			#     where e=expr, i=identifier, k=keyword, op=operator
annotation @<i i=e ...> e	# Scoped annotations are a hybrid of XML and Java annotations
	   @</i>		# Can omit end tag for non-strict XML
           @<i i=e .../> e	# Can use abbreviated empty-element tags
           @<i(i=e,...)> e	# Can also use Java style attributes
           @<i(e)> e
directive  $i e e # preprocessor
dollar	   $i(e,) # super invoke
keyvalue   e:e
slice      e..e
operation  e op e | op e   @isUnary @isBinary 
qualified  i:i:i | i:i=i | i=i | i:i	# parameter declaration
statement  k ...		# declaration, or control construct
subscript  [e,e]		# when appears in index operation
closure    (e,e) -> {e}		# alternative: {(e,e) -> e}

			# Declarations
dotname    i.i			# used in declarations, e.g., import and package
enum       e,e | e e (open)	# used in declarations

iterator   (i in e)	# Primaries
cast       (type) e
invoke     oe(,)[,]		# where oe is (alloc | atom | group)
				# Restricted to e(e) after transformation
index	   e[e]			# Only introduced after transformation
objref     oe(,)[,].f(,)[,]	# where f is atom subset (identifier | methodref | "initially")
atom       @emptyInner between or leading , or ;    @emptyTrailing    @allEmpty
group
command    dotname|id|methodref expr ...  # treated as dotname(expr,...)
				# where expr is limited primary expression
				#	that starts with identifier or literal
allocation new e		# where e is type

EXAMPLE:  (x=1) =>
          expr/group/list/{expr/operation/{expr/atom/identifier,operator=,expr/atom/literal}}

Concrete syntax tags: identifier, literal, keyword, operator, delimiter.

****/ //======================================================================== // Program structuring syntax follows. //========================================================================
ParseAndVisit ::= Start <EOF>
Start ::= ( PackageDeclaration | ImportDeclaration | Link | Invocable | Record | Global | ProcedureNew | Procedure | Method | ClassDeclarationNew | ClassDeclaration | LocalDeclaration | BlockStatement | BlockAsExpr | LambdaAsExpr )*
//====
// Junicon allows optional trailing semicolons in declarations.
//====
PackageDeclaration ::= ( ( PACKAGE Type | PACKAGE TypeStringLiteral ) ( SEMICOL )? )
ImportDeclaration ::= ( IMPORT ( NameOrStringList | TypeStringLiteral | ( STATIC )? ImportName ) ( SEMICOL )? )
Link ::= LINK NameOrStringList ( SEMICOL )?
Invocable ::= INVOCABLE InvocList ( SEMICOL )?
InvocList ::= Invocop ( COMMA Invocop )*
Invocop ::= ( TypeName | TypeStringLiteral COLON TypeIntLiteral | TypeStringLiteral )
Directive ::= DOLLAR Identifier SpacedArgList ( SEMICOL )?
Record ::= ( AnnotationType )? RECORD DeclaredName LPAREN ( ParamList )? RPAREN ( SEMICOL )?
Global ::= ( AnnotationType )? GLOBAL ( Type GlobalVarDeclList SEMICOL | GlobalVarDeclList ( SEMICOL )? )
//========================================================================
// Procedures.
//========================================================================
Procedure ::= ProcedurePrefix SEMICOL ProcBody END ( SEMICOL )?
ProcedureNew ::= ProcedurePrefix ProcBodyNew ( SEMICOL )?
ProcedurePrefix ::= ( AnnotationType )? PROCEDURE DeclaredName LPAREN ( ParamList )? RPAREN
Initial ::= INITIAL Expr SEMICOL
ProcBody ::= ( AllEmptyBlock | BlockLocals ( Initial )? ( ( BlockStatement )+ TrailingEmptyBlock | TrailingEmptyBlock ) )
ProcBodyNew ::= ( LBRACE AllEmptyBlock RBRACE | LBRACE BlockLocals ( Initial )? ( TrailingEmptyBlock | ExprSequence ) RBRACE )
LocalDeclaration ::= LocalDeclarationPrefix ( Type VarInitList | VarInitList ) SEMICOL
LocalDeclarationNoSemicolon ::= LocalDeclarationPrefix ( Type VarInitList | VarInitList )
LocalDeclarationPrefix ::= ( AnnotationType )? ( LOCAL | STATIC )
//========================================================================
// Classes.
//========================================================================
ClassDeclaration ::= ClassPrefix ( SEMICOL )? ClassMethods END ( SEMICOL )?
ClassDeclarationNew ::= ClassPrefix LBRACE ClassMethods RBRACE ( SEMICOL )?
ClassPrefix ::= ( AnnotationType )? CLASS DeclaredName ( Supers )? LPAREN ( ParamList )? RPAREN
ClassMethods ::= ( Method | Global | Record | LocalDeclaration | EmbeddedScript )* ( SEMICOL )? ( InitiallyNew | Initially )?
Supers ::= COLON Super ( COLON Super )*
Super ::= MethodRefType
| Type
Initially ::= InitiallyPrefix SEMICOL ProcBody
InitiallyNew ::= InitiallyPrefix ProcBodyNew ( SEMICOL )?
InitiallyPrefix ::= INITIALLY ( LPAREN ( ParamList )? RPAREN )?
Method ::= ( AbstractMethod | RealMethodNew | RealMethod )
AbstractMethod ::= MethodPrefix ( SEMICOL )?
RealMethod ::= MethodPrefix SEMICOL ProcBody END ( SEMICOL )?
RealMethodNew ::= MethodPrefix ProcBodyNew ( SEMICOL )?
MethodPrefix ::= ( AnnotationType )? ( ABSTRACT )? ( MethodModifiers )? METHOD DeclaredName LPAREN ( ParamList )? RPAREN
MethodModifiers ::= STATIC
//============================================================================
// Declared names (variables and parameters), Types, and Atoms in expressions.
//============================================================================
IdList ::= DeclaredName ( COMMA DeclaredName )*
DeclaredName ::= Identifier
VarInitList ::= VariableInitializer ( COMMA VariableInitializer )*
VariableInitializer ::= ( LocalVariable ASSIGN Expr | LocalVariable )
LocalVariable ::= Identifier
GlobalVarDeclList ::= GlobalVariable ( COMMA GlobalVariable )*
GlobalVariable ::= Identifier
ParamList ::= ( Params LBRACKET_TYPE RBRACKET_TYPE | Params )
Params ::= Param ( COMMA Param )*
Param ::= ( JavaTypedParameter | ( DeclaredParameterName ( COLON Type )? ( ( COLON | EQUALS ) TypeLiteral )? ) )
//====
// Parameter can be param[:type][: or =literal]
//====
JavaTypedParameter ::= ParameterType DeclaredParameterName ( ( EQUALS ) TypeLiteral )?
DeclaredParameterName ::= Identifier
ParameterType ::= ( DotName | Identifier ) ( DOTDOTDOT )?
Type ::= ( GenericType | DotName | Identifier )
GenericType ::= DotNameMaybe LANGLE_TUPLE TypeList RANGLE_TUPLE
TypeList ::= Type ( COMMA Type )*
TypeName ::= Identifier
MethodRefType ::= PackageRef
PackageRef ::= ( DotName COLONCOLON Identifier | SingleDotName COLONCOLON Identifier | EmptyDotName COLONCOLON Identifier )
DotName ::= Identifier ( DOT RelaxedIdentifier )+
SingleDotName ::= Identifier
EmptyDotName ::= AllEmptyAtom
DotNameMaybe ::= ( DotName | Identifier )
ImportName ::= ( ImportDotName | Identifier )
ImportDotName ::= Identifier ( DOT ( Identifier | STAR ) )+
SpacedArgList ::= ( Identifier | Literal )*
NameOrStringList ::= NameOrString ( COMMA NameOrString )*
NameOrString ::= TypeName
| TypeStringLiteral
TypeLiteral ::= Literal
TypeStringLiteral ::= StringLiteral
TypeIntLiteral ::= IntLiteral
//========================================================================
// Parameterized closure.
//========================================================================
Closure ::= LPAREN ( ParamList )? RPAREN ClosureOperator LBRACE ExprSequenceAsBlock RBRACE
ExprSequenceAsBlock ::= ( AllEmptyBlock | BlockLocals ( TrailingEmptyBlock | ExprSequence ) )
//========================================================================
// Block statements and bounded expressions.
//========================================================================
Block ::= LBRACE AllEmptyBlock RBRACE
| LBRACE BlockLocals TrailingEmptyBlock RBRACE
| LBRACE BlockLocals ExprSequence RBRACE
BlockLocals ::= ( LocalDeclaration )*
ExprSequence ::= ( InnerEmptyBlock | Nothing ) ( BlockExpr | Nothing ) ( SEMICOL BlockExpr | SEMICOL InnerEmptyBlock )*
//====
// ExprSequence is to be non-empty, and ends with an expression or innerEmpty.
//	If it would be empty, test and use allEmpty instead.
// Invariant: {AllEmpty} or {x;TrailingEmpty} or {x;y} where x may be InnerEmpty
//====
// We pad leading ";", trailing ";", and ";;" with an empty atom.
// We indicate an empty ExprSequence with AllEmpty().
// A trailing Empty() mimics Icon sequence semantics which ends with ;null.
// Transform must later detect last expr after semicolon to be unbounded.
//====
BlockAsExpr ::= BlockAsGroup
BlockAsGroup ::= Block
LambdaAsExpr ::= LambdaAsGroup
LambdaAsGroup ::= Closure
AllEmptyExpr ::= AllEmptyAtom
AllEmptyBlock ::=
AllEmptyList ::=
InnerEmptyBlock ::= InnerEmptyAtom
InnerEmptyList ::= InnerEmptyAtom
TrailingEmptyBlock ::= TrailingEmptyAtom
TrailingEmptyList ::= TrailingEmptyAtom
AllEmptyAtom ::=
InnerEmptyAtom ::=
TrailingEmptyAtom ::=
BlockStatement ::= InnerEmptyBlock SEMICOL
| BoundedExpr SEMICOL
//====
// Blockstatement ends with semicolon.
//====
BlockExpr ::= BoundedExpr
//====
// BlockExpr need not have semicolon after it.
//====
BoundedExpr ::= ( ( Annotation )+ PlainExpression | PlainExpression )
Expr ::= ( ( Annotation )+ PlainExpression | PlainExpression )
PlainExpression ::= ( Statement | Command | AndExpression )
StatementExpression ::= Statement
//========================================================================
// Control constructs.
//========================================================================
Statement ::= ( If | Case | While | Until | Every | Repeat | Create | Thread | Next | Break | Fail | Suspend | Return | Critical | Puneval )
StatementLookahead ::= ( IF | CASE | WHILE | UNTIL | EVERY | REPEAT | CREATE | THREAD | NEXT | BREAK | FAIL | SUSPEND | RETURN | CRITICAL | PUNEVAL )
If ::= IF BoundedExpr THEN Expr ( ELSE Expr )?
Case ::= CASE BoundedExpr OF LBRACE CaseList RBRACE
CaseList ::= CaseItem ( SEMICOL CaseItem )*
CaseItem ::= ( ( BoundedExpr COLON Expr ) | ( DEFAULT COLON Expr ) )
While ::= WHILE BoundedExpr ( DO BoundedExpr )?
Until ::= UNTIL BoundedExpr ( DO BoundedExpr )?
Every ::= EVERY Expr ( DO BoundedExpr )?
Repeat ::= REPEAT ( BoundedExpr )?
Create ::= CREATE Expr
Thread ::= THREAD Expr
Next ::= NEXT
Break ::= BREAK ( Expr | AllEmptyExpr )
Fail ::= FAIL
Suspend ::= SUSPEND ( SuspendExpr | AllEmptyExpr )
SuspendExpr ::= Expr ( DO BoundedExpr )?
Return ::= RETURN ( BoundedExpr | AllEmptyExpr )
Critical ::= CRITICAL BoundedExpr
Puneval ::= PUNEVAL Expr
Command ::= CommandNameAsAtom ( LimitedPrimaryExpression )+
CommandNameAsAtom ::= ( MethodRef | DotName | StrictIdentifier )
LimitedPrimaryExpression ::= ( LimitedObjectRef | LimitedInvokeExpr )
LimitedObjectRef ::= LimitedInvokeExpr DOT ( ( FieldExpression DOT )* FieldExpression )
LimitedInvokeExpr ::= SingleItem ( Arguments | ArraySuffix )*
//========================================================================
// Expressions.
//========================================================================

//====
// Cascade down for precedence, low to high.
// Higher precedence operators bind more tightly, i.e., are executed first.
//====
AndExpression ::= QmarkExpression ( AND QmarkExpression )*
//====
// Iterative production is left-associative.
//====
QmarkExpression ::= Assignment ( QMARK Assignment )*
//====
// Recursive production is right-associative.
//====
Assignment ::= FirstClassExpression ( ( AssignOperator | AugmentedAssign ) Assignment )?
//====
// Transform must detect Lhs of assign.
//====
FirstClassExpression ::= ( FirstClassOperators )? PmatchExpression
PmatchExpression ::= ToExpression ( PmatchOperators ToExpression )*
//====
// Operations are only allowed to the left of a statement, e.g., if.
// Anything to the right of a statement will bind together.
//====
ToExpression ::= PorExpression ( TO PorExpression ( BY PorExpression )? )?
PorExpression ::= BarExpression ( PorOperators BarExpression )*
BarExpression ::= CompareExpression ( BarOperators CompareExpression )*
CompareExpression ::= ConcatExpression ( CompareOperators ConcatExpression )*
ConcatExpression ::= AddExpression ( ConcatOperators AddExpression )*
AddExpression ::= MultiplyExpression ( AddOperators MultiplyExpression )*
MultiplyExpression ::= CaretExpression ( MultiplyOperators CaretExpression )*
//====
// CaretExpression is right associative via right recursion.
//====
CaretExpression ::= BangExpression ( CARET CaretExpression )?
BangExpression ::= UnaryExpression ( BangOperators UnaryExpression )*
//====
// UnaryExpression is right associative via right recursion.
//====
UnaryExpression ::= ( ( StatementExpression | ( UnaryOperators | UnaryBooleanOperators | NOT ) UnaryExpression ) | PrimaryExpression )
//====
// Transform must detect that unary Not applies to boundedExpression()
//====

//========================================================================
// Primary expressions.
//========================================================================
PrimaryExpression ::= ( CastExpression | CastEmbeddedScript | PrimaryExpressionNoCast )
CastExpression ::= Cast PrimaryExpressionNoCast
CastEmbeddedScript ::= Cast EmbeddedScript
Cast ::= LPAREN Type RPAREN
PrimaryExpressionNoCast ::= ( IteratorExpression | ObjectRef | InvokeExpr )
InvokeExpr ::= ObjectExpr ( Arguments | ArraySuffix )*
//====
// InvokeExpr includes invoke as well as standalone atom and group.
//====
ObjectExpr ::= ( AllocationExpr | MethodRefAsAtom | SingleItem | GroupExpr )
ObjectRef ::= InvokeExpr DOT ( ( FieldExpression DOT )* FieldExpression )
FieldExpression ::= Field ( Arguments | ArraySuffix )*
//====
// ObjectExpr and FieldExpression in Java 8 use: [Arguments()] (ArraySuffix())*
//====
Field ::= ( RelaxedIdentifier )
AllocationExpr ::= NEW Type
Arguments ::= ( Invoke | CoExprInvoke | SuperInvoke )
Invoke ::= LPAREN_EMPTY AllEmptyList RPAREN
| LPAREN ExprList RPAREN
CoExprInvoke ::= LBRACE_EMPTYSET AllEmptyList RBRACE_SET
| LBRACE_SET ExprList RBRACE_SET
SuperInvoke ::= DOLLAR ( INITIALLY | ( Identifier ( DOT Identifier | INITIALLY )? ) ) ( LPAREN_EMPTY AllEmptyList RPAREN | LPAREN ExprList RPAREN )
ArraySuffix ::= LBRACKET_EMPTYINDEX AllEmptyList RBRACKET_INDEX
| LBRACKET_INDEX ( RangeExpr | ExprList ) RBRACKET_INDEX
RangeExpr ::= Expr ( COLON | PCOLON | MCOLON ) Expr
SingleItem ::= ( Identifier | AndKeyword | Literal )
GroupExpr ::= ( Closure | Tuple | Map | EmptyMapComprEnd | Set | Block | CaseMap | List | EmptyMapCompr | ListComprehension )
IteratorExpression ::= InIterator
ArgList ::= ExprList
ExprList ::= ( InnerEmptyList | Nothing ) ( Expr | Nothing ) ( COMMA Expr | COMMA InnerEmptyList )*
//====
// Exprlist is to be non-empty, and ends with an expression or innerEmpty.
//	If it would be empty, test and use allEmpty instead.
// Invariant: (AllEmpty) or (x,TrailingEmpty) or (x,y) where x may be Empty
//====
// We pad leading ",", trailing ",", and ",," with Empty().
// We indicate an empty ExprList with AllEmpty().
//====
RightDelim ::= RPAREN
| RBRACE
| RBRACKET
Nothing ::=
MethodRef ::= ( DotNameAsAtom COLONCOLON RelaxedIdentifier | SingleDotNameAsAtom COLONCOLON RelaxedIdentifier | CastDotNameAsAtom COLONCOLON RelaxedIdentifier | EmptyDotName COLONCOLON RelaxedIdentifier )
//====
// Methodref: x.y::f | ((Cast) x).y::f(z)
//====
CastDotNameAsAtom ::= CastInParen ( DOT Field )*
CastInParen ::= LPAREN SimpleCastExpression RPAREN
SimpleCastExpression ::= Cast IdentifierAsAtom
DotNameAsAtom ::= IdentifierAsAtom ( DOT Field )+
SingleDotNameAsAtom ::= IdentifierAsAtom
IdentifierAsAtom ::= Identifier
MethodRefAsAtom ::= MethodRef
//========================================================================
// Tuple, map, list, and set.
//========================================================================
Tuple ::= LPAREN_EMPTY AllEmptyList RPAREN
| LPAREN ExprList RPAREN
List ::= LBRACKET_EMPTYLIST AllEmptyList RBRACKET
| LBRACKET ExprList RBRACKET
CaseMap ::= LBRACKET_MAP CaseList RBRACKET_MAP
Map ::= LBRACKET_EMPTYMAP COLON RBRACKET
| LBRACKET_MAP MapList RBRACKET_MAP
MapList ::= KeyColonValue ( COMMA KeyColonValue )*
KeyColonValue ::= Expr COLON Expr
EmptyMapCompr ::= COMPR_EMPTYMAP RBRACKET_MAP
EmptyMapComprEnd ::= LBRACKET_EMPTYMAP COMPREND
Set ::= LBRACE_SET ExprList RBRACE_SET
ListComprehension ::= COMPR_EMPTY AllEmptyList COMPREND
| COMPR Expr COMPREND
//========================================================================
// Iterators.
//========================================================================
InIterator ::= ( LPAREN COLON IN Expr RPAREN | LPAREN IdentifierAsExpr IN Expr RPAREN )
IdentifierAsExpr ::= IdentifierAsAtom
LiteralAsAtom ::= Literal
BigLiteralAsAtom ::= BigLiteral
BigLiteralAsExpr ::= BigLiteralAsAtom
//========================================================================
// Annotations.
//========================================================================
AnnotationType ::= Annotation
AnnotationComment ::= ( ANNOTATION_COMMENT_PREFIX SLASH XmlTag GT | XmlTag ( SpacedNamedArgList )? ( SLASH )? GT )
Annotation ::= ( ANNOTATION SLASH XmlTag GT | ANNOTATION XmlTag LPAREN ( NamedArgList | AnnotationExpr )? RPAREN ( SLASH )? GT | ANNOTATION XmlTag ( SpacedNamedArgList )? ( SLASH )? GT )
XmlTag ::= RelaxedDotNameMaybe ( COLON RelaxedDotNameMaybe )?
RelaxedDotNameMaybe ::= RelaxedIdentifier ( DOT RelaxedIdentifier )*
SpacedNamedArgList ::= NamedArg ( NamedArg )*
NamedArgList ::= NamedArg ( COMMA NamedArg )*
NamedArg ::= Identifier EQUALS AnnotationExpr
AnnotationExpr ::= Expr
EmbeddedScript ::= AnnotationType BigLiteralAsExpr
//========================================================================
// Grouped literals and keywords
//========================================================================
Literal ::= IntLiteral
| RealLiteral
| StringLiteral
| CharLiteral
| BigLiteral
| NullLiteral
AndKeyword ::= AND ( Identifier | Fail | NullLiteral )
/*************************************************************************
 * TERMINALS START HERE
 ************************************************************************/

//========================================================================
// Terminals: Reserved Words
//========================================================================
ABSTRACT ::= <ABSTRACT>
BREAK ::= <BREAK>
BY ::= <BY>
CASE ::= <CASE>
CLASS ::= <CLASS>
CREATE ::= <CREATE>
THREAD ::= <THREAD>
CRITICAL ::= <CRITICAL>
DEFAULT ::= <DEFAULT_token>
DO ::= <DO>
ELSE ::= <ELSE>
END ::= <END>
EVERY ::= <EVERY>
FAIL ::= <FAIL>
GLOBAL ::= <GLOBAL>
IF ::= <IF>
IMPORT ::= <IMPORT>
IN ::= <IN>
INITIAL ::= <INITIAL>
INITIALLY ::= <INITIALLY>
INVOCABLE ::= <INVOCABLE>
LINK ::= <LINK>
LOCAL ::= <LOCAL>
METHOD ::= <METHOD>
NEW ::= <NEW>
NEXT ::= <NEXT>
NOT ::= <NOT>
OF ::= <OF>
PACKAGE ::= <PACKAGE>
PROCEDURE ::= <PROCEDURE>
RECORD ::= <RECORD>
REPEAT ::= <REPEAT>
RETURN ::= <RETURN>
STATIC ::= <STATIC>
SUSPEND ::= <SUSPEND>
THEN ::= <THEN>
TO ::= <TO>
UNTIL ::= <UNTIL>
WHILE ::= <WHILE>
//========================================================================
// Terminals: Delimiters
//========================================================================
LPAREN ::= <LPAREN>
RPAREN ::= <RPAREN>
LBRACE ::= <LBRACE>
RBRACE ::= <RBRACE>
LBRACE_CLOSURE ::= <LBRACE>
RBRACE_CLOSURE ::= <RBRACE>
LBRACE_SET ::= <LBRACE>
RBRACE_SET ::= <RBRACE>
LBRACKET ::= <LBRACKET>
RBRACKET ::= <RBRACKET>
LBRACKET_INDEX ::= <LBRACKET>
RBRACKET_INDEX ::= <RBRACKET>
LBRACKET_MAP ::= <LBRACKET>
RBRACKET_MAP ::= <RBRACKET>
LBRACKET_TYPE ::= <LBRACKET>
RBRACKET_TYPE ::= <RBRACKET>
LANGLE_TUPLE ::= <LT>
RANGLE_TUPLE ::= <GT>
COMPR ::= <COMPR>
COMPREND ::= <COMPREND>
LPAREN_EMPTY ::= <LPAREN>
LBRACE_EMPTYSET ::= <LBRACE>
LBRACKET_EMPTYINDEX ::= <LBRACKET>
LBRACKET_EMPTYLIST ::= <LBRACKET>
LBRACKET_EMPTYMAP ::= <LBRACKET>
COMPR_EMPTYMAP ::= <COMPR>
COMPR_EMPTY ::= <COMPR>
SEMICOL ::= <SEMICOLON>
COLON ::= <COLON>
COLONCOLON ::= <COLONCOLON>
COMMA ::= <COMMA>
DOT ::= <DOT>
DOTDOTDOT ::= <DOTDOTDOT>
//========================================================================
// Terminals: Operators
//========================================================================
AND ::= <AND>
QMARK ::= <QMARK>
ASSIGN ::= ( <ASSIGN> )
AssignOperator ::= ( <ASSIGN> | <REVASSIGN> | <REVSWAP> | <SWAP> )
AugmentedAssign ::= ( <AUGMOD> | <AUGAND> | <AUGSTAR> | <AUGINTER> | <AUGPLUS> | <AUGUNION> | <AUGMINUS> | <AUGDIFF> | <AUGSLASH> | <AUGNMLT> | <AUGSLT> | <AUGSLE> | <AUGNMLE> | <AUGNMEQ> | <AUGSEQ> | <AUGEQUIV> | <AUGNMGT> | <AUGNMGE> | <AUGSGT> | <AUGSGE> | <AUGQMARK> | <AUGAT> | <AUGCARET> | <AUGCONCAT> | <AUGNEQUIV> | <AUGSNE> | <AUGNMNE> | <AUGLCONCAT> )
PmatchOperators ::= <PMATCH>
PorOperators ::= <POR>
BarOperators ::= ( <BAR> | <PAND> )
ClosureOperator ::= ( <PASSNONMATCH> )
CompareOperators ::= ( <GT> | <LT> | <EQ> | <LE> | <GE> | <EQUALS> | <LSHIFT> | <RSHIFT> | <SLE> | <EQUIV> | <SGE> | <NMNE> | <SNE> | <NEQUIV> | <PIMDASSN> | <PASSNONMATCH> )
ConcatOperators ::= ( <CONCAT> | <LCONCAT> )
AddOperators ::= ( <PLUS> | <MINUS> | <INCR> | <DECR> )
MultiplyOperators ::= ( <STAR> | <SLASH> | <PERCENT> | <INTER> )
CARET ::= <CARET>
BangOperators ::= ( <BANG> | <BACKSLASH> | <AT> | <SND> | <SNDBK> )
FirstClassOperators ::= ( <FIRSTCLASS> | <FUTURE> | <PIPE> | <COEXPR> | <PARALLEL> )
UnaryOperators ::= ( <TILDE> | <PSETCUR> | <AT> | <BAR> | <CONCAT> | <LCONCAT> | <DOT> | <BANG> | <DECR> | <PLUS> | <STAR> | <CARET> | <INTER> | <MINUS> | <EQUALS> | <NMNE> | <EQ> | <RCV> | <RCVBK> | <SNE> | <EQUIV> | <INCR> | <QMARK> | <NEQUIV> )
UnaryBooleanOperators ::= ( <SLASH> | <BACKSLASH> )
PCOLON ::= <PCOLON>
MCOLON ::= <MCOLON>
DOLLAR ::= <DOLLAR>
AT ::= <AT>
LT ::= <LT>
GT ::= <GT>
SLASH ::= <SLASH>
STAR ::= <STAR>
EQUALS ::= <EQUALS>
PUNEVAL ::= <BACKQUOTE>
//========================================================================
// Terminals: Identifiers
//========================================================================
Identifier ::= ( <IDENTIFIER> | <NEW> | <IN> )
StrictIdentifier ::= ( <IDENTIFIER> )
RelaxedIdentifier ::= ( <IDENTIFIER> | <IN> | <NEXT> | <THREAD> | <INITIALLY> )
//========================================================================
// Terminals: Literals
//========================================================================
BigLiteral ::= <BIG_LITERAL>
IntLiteral ::= ( <INTEGER_LITERAL> | <RADIX_LITERAL> )
RealLiteral ::= <REAL_LITERAL>
CharLiteral ::= <SINGLE_QUOTE_LITERAL>
StringLiteral ::= <STRING_LITERAL>
NullLiteral ::= <NULL_LITERAL>
//========================================================================
// Terminals: Annotations
//========================================================================
ANNOTATION ::= <ANNOTATION>
ANNOTATION_COMMENT_PREFIX ::= <ANNOTATION_COMMENT_PREFIX>